<?php

class Jf_View extends Jf_View_Abstract {

    private $_loaderTypes = array('filter', 'helper');

    private $_escape = 'htmlspecialchars';

    private $_loaders = array();

    private $_helper = array();

    public function __call ($name, $args) {
        $helper = $this -> getHelper ($name);
        return call_user_func_array (array($helper, $name), $args);
    }

    private function _addPluginPath ($type, $classPrefix, array $paths) {
        $loader = $this -> getPluginLoader ($type);
        foreach ($paths as $path) {
            $loader -> addPrefixPath ($classPrefix, $path);
        }
        return $this;
    }

    public function addHelperPath ($path, $classPrefix = 'Zend_View_Helper_') {
        return $this -> _addPluginPath ('helper', $classPrefix, (array) $path);
    }

    public function setHelperPath ($path, $classPrefix = 'Zend_View_Helper_') {
        unset ($this -> _loaders['helper']);
        return $this -> addHelperPath ($path, $classPrefix);
    }

    public function getHelperPath ($name) {
        return $this -> _getPluginPath ('helper', $name);
    }

    public function getHelperPaths () {
        return $this -> getPluginLoader ('helper') -> getPaths ();
    }

    public function getHelper ($name) {
        return $this -> _getPlugin ('helper', $name);
    }

    public function escape ($var) {
        if (in_array ($this -> _escape, array('htmlspecialchars', 'htmlentities'))) {
            return call_user_func ($this -> _escape, $var, ENT_COMPAT, $this -> _encoding);
        }
        if (1 == func_num_args ()) {
            return call_user_func ($this -> _escape, $var);
        }
        $args = func_get_args ();
        return call_user_func_array ($this -> _escape, $args);
    }

    private function _getPlugin ($type, $name) {
        $name = ucfirst ($name);
        switch ($type) {
            case 'filter' :
                $storeVar = '_filterClass';
                $store = $this -> _filterClass;
                break;
            case 'helper' :
                $storeVar = '_helper';
                $store = $this -> _helper;
                break;
        }
        if ( ! isset ($store[$name])) {
            $class = $this -> getPluginLoader ($type) -> load ($name);
            $store[$name] = new $class ();
            if (method_exists ($store[$name], 'setView')) {
                $store[$name] -> setView ($this);
            }
        }
        $this -> $storeVar = $store;
        return $store[$name];
    }

    public function getPluginLoader ($type) {
        $type = strtolower ($type);
        if ( ! in_array ($type, $this -> _loaderTypes)) {
            $e = new Jf_View_Exception (sprintf ('Invalid plugin loader type "%s"; cannot retrieve', $type));
            $e -> setView ($this);
            throw $e;
        }
        if ( ! array_key_exists ($type, $this -> _loaders)) {
            $prefix = 'Jf_View_';
            $pathPrefix = 'Jf/View/';
            $pType = ucfirst ($type);
            switch ($type) {
                case 'filter' :
                case 'helper' :
                default :
                    $prefix .= $pType;
                    $pathPrefix .= $pType;
                    $loader = new Zend_Loader_PluginLoader (array($prefix => $pathPrefix));
                    $this -> _loaders[$type] = $loader;
                    break;
            }
        }
        return $this -> _loaders[$type];
    }

    public static function getView () {
        if ( ! Jf_Registry::isRegistered ('jf_view')) {
            $view = new Jf_View ();
            Jf_Registry::set ('jf_view', $view);
        } else {
            $view = Jf_Registry::get ('jf_view');
        }
        return $view;
    }

}
